#include "sem.h"

#include <stdlib.h>

struct thread_sem {
  int lock;
  unsigned int value;
};

int thread_sem_init(thread_sem_t **sem, unsigned int value)
{
  *sem = malloc(sizeof(thread_sem_t));
  (*sem)->lock= 0;
  (*sem)->value = value;

  return 0;
}

int thread_sem_wait(thread_sem_t *sem)
{
  while (1) // attente active
  {
    while (__sync_val_compare_and_swap(&(sem->lock), 0, 1) == 1); // attend de pouvoir regarder le sémaphore
    if (sem->value == 0)
    {
      __sync_and_and_fetch(&(sem->lock), 0); // on continue d'attendre
    }
    else
    {
      (sem->value)--;
      __sync_and_and_fetch(&(sem->lock), 0);
      break; // on a pris le sémaphore
    }
  }

  return 0;
}

int thread_sem_post(thread_sem_t *sem)
{
  __sync_fetch_and_add(&(sem->value), 1);

  return 0;
}

int thread_sem_getvalue(thread_sem_t *sem, int * sval)
{
  *sval = sem->value;

  return 0;
}

int thread_sem_destroy(thread_sem_t *sem)
{
  free(sem);

  return 0;
}
